home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Night Owl 6
/
Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso
/
039a
/
nstext.zip
/
NS_TEXT.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-12-05
|
38KB
|
895 lines
{$I-,F+}
Unit NS_Text; { v0.6 }
{*****************************************************************************}
{ Contains all elements to manipulate text files. }
{ Author: Michael Weber [71301,1221] }
{ Revision history: }
{ 1) 20 Nov 91 first version released (v0.5) }
{ 2) 1 Dec 91 version 0.6 released }
{ * Added methods SetFAttr & GetFAttr to manipulate file attributes }
{ * Added methods SetFTime & GetFTime to manipulate file time stamps }
{ * Added ability to copy file within its instance ( i.e. no longer }
{ need to destruct instance, copy file, & recreate instance) }
{ * Added ability to instantate leaving file closed (via NS_Closed }
{ enumerated type) }
{ * Added method FileSplit to return subcomponents of the file name }
{ * Methods made recursive where possible to reduce code / increase }
{ integrity }
{ * Private method CClose added to increase integrity }
{ }
{ FileOpenType defines the state to which TextFile is opened as follows: }
{ NS_Reset - Open existing file for input }
{ NS_ReWrite - Create new file for output }
{ NS_Append - Open existing file for output to append }
{ NS_Closed - Leaves the file closed }
{ }
{ The following are personal reminders for future versions. I invite you, }
{ though, to extend NS_Text to address these needs or add new features. }
{ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
{ Idea*** Keep current record pointer in read(ln) & write(ln). }
{ Create Seek Procedure to properly place next read(ln) / write(ln) }
{ Idea*** Parm (in Init) for text buffer size ability to chg. size at runtime }
{ Idea*** Have linked list of open files. }
{ Idea*** Have dialog window to open file... mabey in decendent object... }
{ Question*** Should I allow multiple instances for same file? }
{*****************************************************************************}
Interface {===================================================================}
Const
TextOk : Boolean = True;
TextError : Byte = 0;
Type
FileNameType = PChar;
FileIntegType = (NS_Normal, NS_High);
FileOpenType = (NS_Reset, NS_ReWrite, NS_Append, NS_Closed);
PTextFile = ^TTextFile;
TTextFile = Object
FlushBuffer : Boolean; { Set to TRUE when record buffered to disk }
FileName : FileNameType;
FileInteg : FileIntegType;
F : Text;
FileMode : FileOpenType; { Reset / ReWrite / Append / Closed }
{ TextBuff : Array[0..1023] Of Char; { Buffer for file }
Constructor Init(Name:FileNameType; State:FileOpenType);
Procedure Integrity(Integ:FileIntegType);
Procedure Reset;
Procedure ReWrite;
Procedure Append;
Procedure Flush; Virtual;
Procedure SetFlush;
Procedure Rename(NewName:FileNameType); Virtual;
Procedure FCopy(DestName:FileNameType); Virtual;
Function EOF : Boolean; Virtual;
Function EOLN : Boolean; Virtual;
Function SeekEOF : Boolean; Virtual;
Function SeekEOLN : Boolean; Virtual;
Procedure Read(VAR Item:String); Virtual;
Procedure ReadLn(VAR Item:String); Virtual;
Procedure Write(Item:String); Virtual;
Procedure WriteLn(Item:String); Virtual;
Procedure GetFTime(VAR Time:LongInt); Virtual;
Procedure SetFTime(VAR Time:LongInt); Virtual;
Function FileSplit(Dir, Name, Ext:PChar) : Word; Virtual;
Procedure GetFAttr(VAR Attr:Word); Virtual;
Procedure SetFAttr(VAR Attr:Word); Virtual;
Destructor Close; Virtual;
Destructor Erase; Virtual;
Private
Procedure CClose;
End;{Object}
Implementation {==============================================================}
Uses
WinDOS; { Borland DOS unit }
Constructor TTextFile.Init;
{--------------------------------------------------------------------------}
{ Extensible? NO - Constructors are not extensible }
{ }
{ Error information: }
{ None - no system procedures called }
{ }
{ First we allocate 80 bytes of heap space for the qualified file name. }
{ Instead of calling the system procedures Reset, ReWrite, and Append, we }
{ call the objects methods for consistancy of error handling and }
{ protocol. }
{--------------------------------------------------------------------------}
Begin
GetMem(FileName, fsPathName+1); { Allow room for #0 }
FileExpand(FileName, Name);
FileMode := State;
Assign(F, FileName);
{ SetTextBuf(F, TextBuff); }
Case FileMode Of
NS_Reset : Begin
Reset;
End; {Reset}
NS_ReWrite : Begin
ReWrite;
End; {ReWrite}
NS_Append : Begin
Append;
End; {Append}
End; {Case}
End;
{EndConstructor}
Procedure TTextFile.Integrity;
{--------------------------------------------------------------------------}
{ Extensible? NO - only purpose of method is to set Integrity level }
{--------------------------------------------------------------------------}
Begin
FileInteg := Integ;
End;
{EndProcedure}
Procedure TTextFile.Reset;
{--------------------------------------------------------------------------}
{ Error information: }
{ Reset : 2 File not found }
{ 3 Path not found }
{ 4 Too many open files }
{ 5 File access denied }
{ 102 File not assigned }
{--------------------------------------------------------------------------}
Begin
FlushBuffer := False; { Initialize flag for Flush }
FileMode := NS_Reset;
System.Reset(F);
Case IOResult Of
2 : Begin { File not found }
System.ReWrite(F);
Reset;
End; {2}
3 : Begin { Path not found }
TextOK := False;
TextError := 3;
End; {3}
4 : Begin { Too many open files }
TextOK := False;
TextError := 4;
End; {4}
5 : Begin { File access denied }
TextOK := False;
TextError := 5;
End; {5}
102 : Begin { File not assigned }
TextOK := False; { This should never happen! }
TextError := 102;
End; {102}
End; {Case}
End;
{EndProcedure}
Procedure TTextFile.ReWrite;
{--------------------------------------------------------------------------}
{ Error information: }
{ ReWrite : 3 Path not found }
{ 4 Too many open files }
{ 5 File access denied }
{ 102 File not assigned }
{--------------------------------------------------------------------------}
Begin
FlushBuffer := False; { Initialize flag for Flush }
FileMode := NS_ReWrite;
System.ReWrite(F);
Case IOResult Of
3 : Begin { Path not found }
TextOK := False;
TextError := 3;
End; {3}
4 : Begin { Too many open files }
TextOK := False;
TextError := 4;
End; {4}
5 : Begin { File access denied }
TextOK := False;
TextError := 5;
End; {5}
102 : Begin { File not assigned }
TextOK := False; { This should never happen! }
TextError := 102;
End; {102}
End; {Case}
End;
{EndProcedure}
Procedure TTextFile.Append;
{--------------------------------------------------------------------------}
{ Error information: }
{ Append : 2 File not found }
{ 3 Path not found }
{ 4 Too many open files }
{ 5 File access denied }
{ 102 File not assigned }
{--------------------------------------------------------------------------}
Begin
FlushBuffer := False; { Initialize flag for Flush }
FileMode := NS_Append;
System.Append(F);
Case IOResult Of
2 : System.ReWrite(F); { File Not Found }
3 : Begin { Path not found }
TextOK := False;
TextError := 3;
End; {3}
4 : Begin { Too many open files }
TextOK := False;
TextError := 4;
End; {4}
5 : Begin { File access denied }
TextOK := False;
TextError := 5;
End; {5}
102 : Begin { File not assigned }
TextOK := False; { This should never happen! }
TextError := 102;
End; {102}
End; {Case}
End;
{EndProcedure}
Procedure TTextFile.Flush;
{--------------------------------------------------------------------------}
{ Error information: }
{ Flush : 101 Disk write error }
{ 103 File not open }
{--------------------------------------------------------------------------}
Begin
If (FlushBuffer) Then
Begin
System.Flush(F);
Case IOResult Of
101 : Begin { Disk write error }
TextOK := False;
TextError := 101;
End; {101}
103 : Begin { File not open }
TextOK := False; { This should never happen! }
TextError := 103;
End; {3}
Else
FlushBuffer := False; { Clear Flag }
End; {Case}
End
{EndIf}
End;
{EndProcedure}
Procedure TTextFile.SetFlush;
{--------------------------------------------------------------------------}
{ Extensible? NO - only purpose of method is to set FlushBuffer = True }
{--------------------------------------------------------------------------}
Begin
FlushBuffer := True;
End;
{EndProcedure}
Procedure TTextFile.Rename;
{--------------------------------------------------------------------------}
{ Error information: }
{ Close : 101 Disk write error }
{ 103 File not open }
{ ReName : 2 File not found }
{ 3 Path not found }
{ 5 File access denied }
{ 17 Cannot rename across drives }
{ 102 File not assigned }
{--------------------------------------------------------------------------}
Begin
CClose; { ReName must NEVER be used on an open file! }
If (TextOK) Then
Begin
FileExpand(FileName, NewName);
System.Rename(F, FileName);
Case IOResult Of
2 : Begin { File not found }
TextOK := False;
TextError := 2;
End; {2}
3 : Begin { Path not found }
TextOK := False;
TextError := 3;
End; {3}
5 : Begin {File access denied }
TextOK := False;
TextError := 5;
End; {5}
17 : Begin { Cannot rename across drives }
TextOK := False;
TextError := 17;
End; {17}
102 : Begin { File not assigned }
TextOK := False; { This should never happen! }
TextError := 102;
End; {102}
Else { After ReName, open file for processing again }
Begin
Case FileMode Of
NS_Reset : Reset;
NS_ReWrite : ReWrite;
NS_Append : Append;
End; {Case}
End;
End; {Case}
End;
{EndIf}
End;
{EndProcedure}
Procedure TTextFile.FCopy;
{--------------------------------------------------------------------------}
{ Error information: }
{ Reset : 2 File not found }
{ 3 Path not found }
{ 4 Too many open files }
{ 5 File access denied }
{ 102 File not assigned }
{ ReWrite : 3 Path not found }
{ 4 Too many open files }
{ 5 File access denied }
{ 102 File not assigned }
{ Close : 101 Disk write error }
{ 103 File not open }
{--------------------------------------------------------------------------}
Var
Buf : Array[1..2048] Of Char;
CopyName : FileNameType;
FFrom : File; { Untyped file }
FTo : File; { Untyped file }
NumRead : Word;
NumWritten : Word;
Begin
{--------------------------------------------------------------------}
{ Close file 'F' and reopen as an untyped input file }
{--------------------------------------------------------------------}
CClose;
Assign(FFrom, FileName);
System.Reset(FFrom);
Case IOResult Of
2 : Begin { File not found }
System.ReWrite(F);
Reset;
End; {2}
3 : Begin { Path not found }
TextOK := False;
TextError := 3;
End; {3}
4 : Begin { Too many open files }
TextOK := False;
TextError := 4;
End; {4}
5 : Begin { File access denied }
TextOK := False;
TextError := 5;
End; {5}
102 : Begin { File not assigned }
TextOK := False; { This should never happen! }
TextError := 102;
End; {102}
End; {Case}
{--------------------------------------------------------------------}
{ Allocate memory for CopyName and open for untyped output }
{--------------------------------------------------------------------}
GetMem(CopyName, fsPathName+1); { Allow room for #0 }
FileExpand(CopyName, DestName);
Assign(FTo, CopyName);
System.ReWrite(FTo);
Case IOResult Of
3 : Begin { Path not found }
TextOK := False;
TextError := 3;
End; {3}
4 : Begin { Too many open files }
TextOK := False;
TextError := 4;
End; {4}
5 : Begin { File access denied }
TextOK := False;
TextError := 5;
End; {5}
102 : Begin { File not assigned }
TextOK := False; { This should never happen! }
TextError := 102;
End; {102}
End; {Case}
{--------------------------------------------------------------------}
{ Proveded we have no errors, copy contents from the untyped source }
{ file to the untyped target file }
{--------------------------------------------------------------------}
If (TextOK) Then
Repeat
BlockRead(FFrom, Buf, SizeOf(Buf), NumRead);
BlockWrite(FTo, Buf, NumRead, NumWritten);
Until (NumRead = 0) or (NumWritten <> NumRead);
{EndIf}
{--------------------------------------------------------------------}
{ Close both the untyped source and untyped target files }
{--------------------------------------------------------------------}
System.Close(FFrom);
Case IOResult Of
101 : Begin { Disk write error }
TextOK := False;
TextError := 101;
End; {101}
103 : { We don't worry about a 103 - obviously! }; { File not open }
End; {Case}
System.Close(FTo);
Case IOResult Of
101 : Begin { Disk write error }
TextOK := False;
TextError := 101;
End; {101}
103 : { We don't worry about a 103 - obviously! }; { File not open }
End; {Case}
{--------------------------------------------------------------------}
{ Dispose dynamic memory allocated for target file name }
{--------------------------------------------------------------------}
If (CopyName <> nil) Then { Dispose dynamic memory }
FreeMem(CopyName, fsPathName+1);
{EndIf}
{--------------------------------------------------------------------}
{ Reopen file 'F' in the state it maintained before FCopy }
{--------------------------------------------------------------------}
Case FileMode Of
NS_Reset : Reset;
NS_ReWrite : ReWrite;
NS_Append : Append;
End; {Case}
End;
{EndProcedure}
Function TTextFile.EOF;
{--------------------------------------------------------------------------}
{ Error information: }
{ EOF : 103 File not open }
{ 104 File not open for input }
{--------------------------------------------------------------------------}
Begin
EOF := System.EOF(F);
Case IOResult Of
103 : Begin { File not open }
TextOK := False;
TextError := 103;
End; {103}
104 : Begin { File not open for input }
TextOK := False;
TextError := 104;
End; {104}
End; {Case}
End;
{EndFunction}
Function TTextFile.EOLN;
{--------------------------------------------------------------------------}
{ Error information: }
{ EOLN : 104 File not open for input }
{--------------------------------------------------------------------------}
Begin
EOLN := System.EOLN(F);
Case IOResult Of
104 : Begin { File not open for input }
TextOK := False;
TextError := 104;
End; {104}
End; {Case}
End;
{EndFunction}
Function TTextFile.SeekEOF;
{--------------------------------------------------------------------------}
{ Error information: }
{ SeekEOF : 104 File not open for input }
{--------------------------------------------------------------------------}
Begin
SeekEOF := System.SeekEOF(F);
Case IOResult Of
104 : Begin { File not open for input }
TextOK := False;
TextError := 104;
End; {104}
End; {Case}
End;
{EndFunction}
Function TTextFile.SeekEOLN;
{--------------------------------------------------------------------------}
{ Error information: }
{ SeekEOLN: 104 File not open for input }
{--------------------------------------------------------------------------}
Begin
SeekEOLN := System.SeekEOLN(F);
Case IOResult Of
104 : Begin { File not open for input }
TextOK := False;
TextError := 104;
End; {104}
End; {Case}
End;
{EndFunction}
Procedure TTextFile.Read;
{--------------------------------------------------------------------------}
{ Extensible? YES - Allows for further definition of input variables }
{ Error information: }
{ Read : 103 File not open }
{ 104 File not open for input }
{ 106 Invalid numeric format }
{--------------------------------------------------------------------------}
Begin
System.Read(F, Item);
Case IOResult Of
103 : Begin { File not open }
TextOK := False;
TextError := 103;
End; {103}
104 : Begin { File not open for input }
TextOK := False;
TextError := 104;
End; {104}
106 : Begin { Invalid numeric format }
TextOK := False;
TextError := 106;
End; {106}
End; {Case}
End;
{EndProcedure}
Procedure TTextFile.ReadLn;
{--------------------------------------------------------------------------}
{ Extensible? YES - Allows for further definition of input variables }
{ Error information: }
{ ReadLn : 104 File not open for input }
{ 106 Invalid numeric format }
{--------------------------------------------------------------------------}
Begin
System.ReadLn(F, Item);
Case IOResult Of
104 : Begin { File not open for input }
TextOK := False;
TextError := 104;
End; {104}
106 : Begin { Invalid numeric format }
TextOK := False;
TextError := 106;
End; {106}
End; {Case}
End;
{EndProcedure}
Procedure TTextFile.Write;
{--------------------------------------------------------------------------}
{ Extensible? YES - Allows for further definition of output variables. }
{ BE SURE TO CALL SetFlushBuffer! }
{ Error information: }
{ Write : 101 Disk write error }
{ 103 File not open }
{ 105 File not open for output }
{--------------------------------------------------------------------------}
Begin
System.Write(F, Item);
Case IOResult Of
101 : Begin { File not open }
TextOK := False;
TextError := 101;
End; {101}
103 : Begin { File not open }
TextOK := False;
TextError := 103;
End; {103}
105 : Begin { File not open for output }
TextOK := False;
TextError := 105;
End; {105}
Else
If (FileInteg = NS_High) Then
Flush
Else
FlushBuffer := True; { Data buffered to disk }
{EndIf}
End; {Case}
End;
{EndProcedure}
Procedure TTextFile.WriteLn;
{--------------------------------------------------------------------------}
{ Extensible? YES - Allows for further definition of output variables. }
{ BE SURE TO CALL SetFlushBuffer! }
{ Error information: }
{ WriteLn : 101 Disk write error }
{ 105 File not open for output }
{--------------------------------------------------------------------------}
Begin
FlushBuffer := True; { Data buffered to disk }
System.WriteLn(F, Item);
Case IOResult Of
101 : Begin { File not open }
TextOK := False;
TextError := 101;
End; {101}
105 : Begin { File not open for output }
TextOK := False;
TextError := 105;
End; {105}
Else
If (FileInteg = NS_High) Then
Flush
Else
FlushBuffer := True; { Data buffered to disk }
{EndIf}
End; {Case}
End;
{EndProcedure}
Procedure TTextFile.GetFTime;
{--------------------------------------------------------------------------}
{ Error information: }
{ GetFTime : 6 Invalid file handle }
{--------------------------------------------------------------------------}
Begin
If (FileMode = NS_Closed) Then
Begin
Reset;
GetFTime(Time);
CClose;
End
Else
Begin
WinDOS.GetFTime(F, Time);
Case IOResult Of
6 : Begin { Invalid file handle }
TextOK := False;
TextError := 6;
End; {6}
End; {Case}
End;
{EndIf}
End;
{EndProcedure}
Procedure TTextFile.SetFTime;
{--------------------------------------------------------------------------}
{ Error information: }
{ SetFTime : 6 Invalid file handle }
{--------------------------------------------------------------------------}
Begin
If (FileMode = NS_Closed) Then
Begin
Reset;
SetFTime(Time);
CClose;
End
Else
Begin
WinDOS.SetFTime(F, Time);
Case IOResult Of
6 : Begin { Invalid file handle }
TextOK := False;
TextError := 6;
End; {6}
End; {Case}
End;
{EndIf}
End;
{EndProcedure}
Function TTextFile.FileSplit;
{--------------------------------------------------------------------------}
Begin
FileSplit := WinDOS.FileSplit(FileName, Dir, Name, Ext);
End;
{EndFunction}
Procedure TTextFile.GetFAttr;
{--------------------------------------------------------------------------}
{ Error information: }
{ GetFAttr : 3 Invalid path }
{ 5 File access denied }
{--------------------------------------------------------------------------}
Begin
If (FileMode <> NS_Closed) Then
Begin
CClose;
GetFAttr(Attr);
Case FileMode Of
NS_Reset : Reset;
NS_ReWrite : ReWrite;
NS_Append : Append;
End; {Case}
End
Else
Begin
WinDOS.GetFAttr(F, Attr);
Case IOResult Of
3 : Begin { Invalid path }
TextOK := False;
TextError := 3;
End; {3}
5 : Begin { File access denied }
TextOK := False;
TextError := 5;
End; {5}
End; {Case}
End;
{EndIf}
End;
{EndProcedure}
Procedure TTextFile.SetFAttr;
{--------------------------------------------------------------------------}
{ Error information: }
{ SetFAttr : 3 Invalid path }
{ 5 File access denied }
{--------------------------------------------------------------------------}
Begin
If (FileMode <> NS_Closed) Then
Begin
CClose;
SetFAttr(Attr);
Case FileMode Of
NS_Reset : Reset;
NS_ReWrite : ReWrite;
NS_Append : Append;
End; {Case}
End
Else
Begin
WinDOS.SetFAttr(F, Attr);
Case IOResult Of
3 : Begin { Invalid path }
TextOK := False;
TextError := 3;
End; {3}
5 : Begin { File access denied }
TextOK := False;
TextError := 5;
End; {5}
End; {Case}
End;
{EndIf}
End;
{EndProcedure}
Destructor TTextFile.Close;
{--------------------------------------------------------------------------}
{ Error information: }
{ Close : 101 Disk write error }
{ 103 File not open }
{--------------------------------------------------------------------------}
Begin
CClose;
If (FileName <> nil) Then { Dispose dynamic memory allocated in Init }
FreeMem(FileName, fsPathName+1);
{EndIf}
End;
{EndFunction}
Destructor TTextFile.Erase;
{--------------------------------------------------------------------------}
{ Error information: }
{ Close : 101 Disk write error }
{ 103 File not open }
{ Erase : 2 File not found }
{ 3 Path not found }
{ 5 File access denied }
{ 102 File not assigned }
{--------------------------------------------------------------------------}
Begin
CClose; { Erase must NEVER be used on an open file! }
If (TextOK) Then
Begin
System.Erase(F);
Case IOResult Of
2 : Begin
TextOK := False;
TextError := 2;
End; {2}
3 : Begin
TextOK := False;
TextError := 3;
End; {3}
5 : Begin
TextOK := False;
TextError := 5;
End; {5}
102 : Begin
TextOK := False;
TextError := 102;
End; {102}
End; {Case}
End;
{EndIf}
If (FileName <> nil) Then { Dispose dynamic memory allocated in Init }
FreeMem(FileName, fsPathName+1);
{EndIf}
End;
{EndProcedure}
Procedure TTextFile.CClose;
{--------------------------------------------------------------------------}
{ Error information: }
{ Close : 101 Disk write error }
{ 103 File not open }
{--------------------------------------------------------------------------}
Begin
System.Close(F);
Case IOResult Of
101 : Begin { Disk write error }
TextOK := False;
TextError := 101;
End; {101}
103 : { We don't worry about a 103 - obviously! }; { File not open }
End; {Case}
End;
{EndFunction}
End.
{$F-}